package de.gwtprime.util;

import java.io.IOException;
import java.io.Reader;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import de.gwtprime.shared.SharedHelper;

public class Helper {

	/**
	 * Open short positions as well.
	 */
	public static boolean enableShortPosition = true;
	
	/**
	 * Logger
	 */
	private final static Logger logger = Logger.getLogger(Helper.class.getName());

	public final static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	public final static DecimalFormat df =   new DecimalFormat  ( "0.0" );
	
	/**
	 * Get the maximum of the given doubles
	 * @param doubles
	 * @return
	 */
	public static Double getMaximum(Double ...doubles){

		Double max= Double.MIN_VALUE;
		for (Double i : doubles)
			max = Math.max(max, i);

		return max;
	}


	public static Double round(Double number){
		BigDecimal a = new BigDecimal(number); 
		a = a.divide(new BigDecimal("1"), 2, BigDecimal.ROUND_HALF_UP); 
		return a.doubleValue();
	}

	/**
	 * Add one day to given date
	 */
	public static Date addOneDayToDate(Date date) {
		Calendar calTemp = Calendar.getInstance();
		calTemp.setTime(date);
		calTemp.add(Calendar.DAY_OF_MONTH, 1);

		date = calTemp.getTime();

		return date;
	}

	/**
	 * Compare if dates have the same day -> year, month, day (ignore time)
	 */
	public static int compareDates(Calendar c1, Calendar c2) {
		if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)) 
			return c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR);
		if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)) 
			return c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
		return c1.get(Calendar.DAY_OF_MONTH) - c2.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * Safely close the given reader
	 * @param reader
	 */
	public static void safeCloseReader(Reader reader){

		if(reader!=null){
			try {
				reader.close();
			} catch (IOException e) {
				logger.warn("Could not close reader", e);
			}
		}
	}


	/**
	 * Add number of days to the given and return a new date
	 * @param date
	 * @param days
	 * @return
	 */
	public static Date addDaysToDate(Date date, int days){

		long newDateLong = date.getTime()+(long)days*24l*60l*60l*1000l;

		return new Date(newDateLong);
	}

	/**
	 * Get a random hash. Used for the activation email.
	 * @return Random generated md5 hash.
	 */
	public static String getRandomHash(){
		String stringToEncrypt = String.valueOf(Math.random());
		
		/* Computation */
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			logger.error("MD5 hash algorithm not found", e);
		}
		
		md5.update(stringToEncrypt.getBytes());
		byte[] result = md5.digest();

		/* Ausgabe */
		StringBuffer hexString = new StringBuffer();
		for (int i=0; i<result.length; i++) {
			hexString.append(Integer.toHexString(0xFF & result[i]));
		}

		return hexString.toString();
	}
	
	/**
	 * Check if string is null or empty
	 * @param string String to check.
	 * @return
	 */
	public static boolean isNullOrEmpty(String string){
		if(string==null) return true;
		if(string.isEmpty()) return true;
		return false;
	}
	
	/**
	 * Build the activation Link
	 * @param userName
	 * @param hash
	 * @return
	 */
	public static String getActivationLink(String userName, String hash){
		
		String link = "";
		
		//link += String.format("%s/activate?email=%s&hash=%s",domain,userName,hash);
		
		return link;
		
	}
	
	/**
	 * Validate given email with regex (on server side -> There is also a validator on client side (AppUtils)).
	 * @param mail
	 * @return
	 */
	public static boolean validateEmail(String mail){
		
		Pattern pattern = Pattern.compile(SharedHelper.emailValidationRegex);
		Matcher matcher = pattern.matcher(mail);
		
		return matcher.find();
	}
}
